package org.beeware.android.service;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;

import com.chaquo.python.PyObject;
import com.chaquo.python.Python;
import com.chaquo.python.android.AndroidPlatform;

import org.beeware.android.util.PhoneInfo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import sc.ktv.external.youtube.DlLinks;
import sc.ktv.external.youtube.IYoutubeDl;
import sc.ktv.external.youtube.IYoutubeDlLinksCallback;

/**
 *
 */
public class YoutubeDlService extends Service {

    private static final String TAG = YoutubeDlService.class.getSimpleName();

    private static final int REPORT_MSG = 1;

    private RemoteCallbackList<IYoutubeDlLinksCallback> mCallbacks = new RemoteCallbackList<IYoutubeDlLinksCallback>();

    private static final ExecutorService sExecutor = Executors.newSingleThreadExecutor();

    private Python mPython;

    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case REPORT_MSG: {
                    String links = null;
                    if (msg.obj != null) {
                        links = (String) msg.obj;
                    }
                    notifyFinish(links);
                }
                break;

                default:
                    break;
            }
        }
    };

    public YoutubeDlService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (!Python.isStarted()) {
            AndroidPlatform platform = new AndroidPlatform(this);
            platform.redirectStdioToLogcat();
            Python.start(platform);
        }
        mPython = Python.getInstance();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        sExecutor.shutdown();
        mCallbacks.kill();
        mHandler.removeMessages(REPORT_MSG);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new IYoutubeDl.Stub() {
            @Override
            public void getYoutubeDlLinks(final String url) {
                Log.d(TAG, "AppVerName:V" + PhoneInfo.getAppVerName(YoutubeDlService.this));
                if (!TextUtils.isEmpty(url)) {
                    sExecutor.execute(() -> {
                        //调用python代码
                        PyObject pyObject = mPython.getModule("youtube_dl").callAttr("get_download_link", url);
                        Message msg = mHandler.obtainMessage(REPORT_MSG);
                        if (pyObject != null) {
                            msg.obj = pyObject.toJava(String.class);
                            Log.d(TAG, "youtubeDlUrls:" + msg.obj);
                        }
                        mHandler.sendMessage(msg);
                    });
                } else {
                    notifyFinish(null);
                }
            }

            @Override
            public void registerDlLinksCallback(IYoutubeDlLinksCallback cb) {
                if (cb != null) {
                    mCallbacks.register(cb);
                }
            }

            @Override
            public void unregisterDlLinksCallback(IYoutubeDlLinksCallback cb) {
                if (cb != null) {
                    mCallbacks.unregister(cb);
                }
            }
        };
    }

    /**
     * 通知下载完成
     *
     * @param links
     */
    private void notifyFinish(String links) {
        DlLinks dlLinks = new DlLinks();
        dlLinks.setLinks(links);
        final int n = mCallbacks.beginBroadcast();
        for (int i = 0; i < n; i++) {
            try {
                //将收到的值回调给aidl定义的方法
                mCallbacks.getBroadcastItem(i).dlLinks(dlLinks);
            } catch (RemoteException e) {
            }
        }
        //结束回调
        mCallbacks.finishBroadcast();
    }
}